<?php

namespace App\Libraries;

class RedisQueue {

    /**
     * 初始化
     * @param $redis redis实例
     * @param $queue_key 队列key
     * @param $queue_num 队列个数
     * add by zhixiao476@gmail.com
     * 2019年01月14日16:50:32
     */
    public function __construct(object $redis, string $queue_key, int $queue_num){
        if (empty($redis)){
            $this->redis = getRedis(0);
        }else{
            $this->redis = $redis;
        }
        $this->queue_key = $queue_key;
        $this->queue_num = $queue_num;
    }

    /**
     * 队列业务处理
     * add by zhixiao476@gmail.com
     * 2019年01月14日16:52:14
     */
    public function handle($msg){
        return new RedisQueueException("请继承后重写该业务方法！");
    }

    /**
     * 阻塞等待队列消息
     * add by zhixiao476@gmail.com
     * 2019年01月14日16:53:28
     */
    public function wait_queue($queue_id = 0, $timeout = 2){
        while (True){
            $key = sprintf($this->queue_key, $queue_id);
            $msg = $this->redis->lpop($key);
            if ($msg){
                $this->handle($msg);
            }else{
                return new RedisQueueException("没有获取到该队列的消息！");
            }
        }
    }

    /**
     * 将消息放入到redis 中
     * add by zhixiao476@gmail.com
     * 2019年01月14日16:58:18
     */
    public function push_queue($hash_value, $msg_data){
        // 一般是账号的md5值，然后取前两位，然后取余，取余值为当前队列长度
        if ($this->queue_num == 0){
            $queue_id = 0;
        }else{
            $queue_id = hash_valueHex($hash_value, $this->queue_num);
        }
        $queue_key = sprintf($this->queue_key, $queue_id);
        $this->redis->rpush($queue_key, json_encode($msg_data));
        return true;
    }
}

class RedisQueueException extends \Exception{

    public function __construct(string $message = "", int $code = 0, Throwable $previous = null){
        parent::__construct($message, $code, $previous);
    }
}
